module.exports = function(lab) {
    return {

        // 导入sku查询逻辑 ： 判断商品条形码是否存在
            // 商品条形码存在   判断商品编码是否存在
                // 商品编码存在时 再判断包装单位和包装规格
                    // 存在 根据商品条形码、商品编码、包装单位和包装规格、零售单位查询
                    // 不存在时 根据商品条形码、商品编码、包装规格为0、零售单位查询
                // 商品编码不存在时 再判断包装单位和包装规格
                    // 存在 根据商品条形码、包装单位和包装规格、零售单位查询
                    // 不存在时 根据商品条形码、包装规格为0、零售单位查询
            // 商品条形码不存在 再判断包装单位和包装规格
                // 存在 根据商品编码、包装单位和包装规格、零售单位查询
                // 不存在时 根据商品编码、包装规格为0、零售单位查询
        @findSKU  : function(ouid, {barcode, item_code, retail_unit, package, package_sku}) {

            let query;

            if (!retail_unit) {
                retail_unit = "";
            }

            if (barcode) {

                if (item_code) {

                    // WynnREADME : 我这么操作，其他地方仿照这个地方处理即可
                    if (package && package_sku) {
                        query = ["barcode == ? && item_code == ? && package == ? && package_sku == ? && ouid == ? && retail_unit == ?", barcode, item_code, package, parseInt(package_sku), ouid, retail_unit];
                    } else  {
                        query = ["barcode == ? && item_code == ? && package == null && package_sku == ? && ouid == ? && retail_unit == ?", barcode, item_code, 0, ouid, retail_unit];
                    }

                } else {

                    if (package && package_sku) {
                        query = ["barcode == ? && item_code == null && package == ? && package_sku == ? && retail_unit == ? && ouid == ?", barcode, package, package_sku, retail_unit, ouid];
                    } else {
                        query = ["barcode == ? && item_code == null && package == null && package_sku == ? && retail_unit == ? && ouid == ?", barcode, 0, retail_unit, ouid];
                    }

                }

            } else {

                if (package && package_sku) {
                    query = ["item_code == ? && barcode == null && package == ? && package_sku == ? && retail_unit == ? && ouid == ?", item_code, package, parseInt(package_sku), retail_unit, ouid];
                } else {
                    query = ["item_code == ? && barcode == null && package == null && package_sku == ? && retail_unit == ? && ouid == ?", item_code, 0, retail_unit, ouid];
                }

            }

            return lab.sqlite.find("slime_trader_skus", {"!": query})
        },

        @importSKU: function(ouid, { barcode, item_code, retail_unit, package, package_sku, name, brand, category, trader_price, image_url, memo }) {

            return lab.snapshot(function(snapshot) {

                return snapshot.slime.trader.@findSKU(ouid, {barcode, item_code, retail_unit, package, package_sku}).then(function(result) {

                    let existingSKU;
                    let newTraderSKU;

                    if (result.records.length) {

                        existingSKU = result.records[0];

                    } else {

                        existingSKU = {
                            "id": @.uuid(),
                            "ouid": ouid,
                            "retail_unit" : retail_unit || "",
                            "item_code": item_code ? item_code : undefined,
                            "barcode": barcode ? barcode : undefined,
                            "package_sku": package_sku && package ? parseInt(package_sku) : 0,
                            "package": package_sku && package ? package : undefined,
                            "create_date": Date.now()
                        }

                        newTraderSKU = true;
                    }

                    var skuData  = {};

                    if (!name && newTraderSKU) {
                        throw @lab.errors.invalid_parameters
                    }

                    skuData["name"] = name;

                    skuData["category"] = category;
                    skuData["brand"] = brand;

                    skuData["trader_price"] = Math.round(parseFloat(trader_price) * 100);

                    skuData["memo"] = memo;

                    skuData["last_update"] = Date.now();
                    skuData["is_removed"] = false;

                    skuData["image_url"] = image_url;

                    if (result.records.length) {

                        @.async(function() {
                            snapshot.update("slime_trader_skus", existingSKU, skuData).pipe(this);
                        }).then(function(savedSKU) {

                            snapshot.sqlite.find("slime_trader_skus", {
                                "!": "id != source_id",
                                "source_id": savedSKU.source_id,
                                "ouid": ["!=", ouid]
                            }).then(function(result) {

                                if (result.records.length) {

                                    @.async.all(result.records, function(record) {

                                        snapshot.update("slime_trader_skus", record, skuData).pipe(this)

                                    }).pipe(this)

                                } else {
                                    this.next()
                                }

                            }).pipe(this)

                        }).pipe(this)

                    } else {

                        @.async(function () {
                            snapshot.create("slime_trader_skus", @.merge.simple(skuData, existingSKU)).pipe(this);
                        }).then(function(savedSKU) {

                            snapshot.sqlite.find("slime_traders", {
                                "ouid": ouid
                            }).then(function(result) {

                                if (result.records.length) {

                                    @.async.all(result.records, function(record) {

                                        if (record.account_ouid) {

                                            snapshot.create("slime_trader_skus", @.merge.simple(savedSKU, {
                                                id: @.uuid(),
                                                source_id: savedSKU.id,
                                                source_ouid: savedSKU.ouid,
                                                ouid: record.account_ouid
                                            })).pipe(this)

                                        } else {
                                            this.next()
                                        }

                                    }).pipe(this)
                                } else {
                                    this.next()
                                }
                            }).pipe(this)

                        }).pipe(this)

                    }

                })
            })
        },
        @getSKUByID : function(currentOU, id){
            return lab.find("slime_trader_skus",{
                id : id,
                ouid : currentOU.id,
            });
        },
        getSKUByID : function(session,id){
            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }
            return lab.slime.brand.@getSKUByID(session.currentOU,id)
        },
        /**
         * @api {jsonrpc} slime@trader.searchSKUs(form)=result slime@trader.searchSKUs
         * @apiDescription 查询符合搜索条件的商品数据
         * @apiGroup slime
         * @apiParam (form) {Number} [start=0] 分页开始
         * @apiParam (form) {Number} [limit=10] 分页最大
         * @apiParam (form) {String} brand 品牌
         * @apiParam (form) {String} category 品类
         * @apiParam (form) {String} keyword 名称(name)或商品条形码(barcode)
         * @apiParam (form) {Number} price_low 价格范围中的低价格
         * @apiParam (form) {Number} price_high 价格范围中的高价格
         * @apiParam (form) {Boolean} price_high 价格范围中的高价格
         *
         * @apiSuccess (result) {Number} total 商品总数
         * @apiSuccess (result) {TraderSKUList} list 商品列表
         * @apiSuccess (TraderSKU) {String} id 商品id
         * @apiSuccess (TraderSKU) {String} brand 品牌
         * @apiSuccess (TraderSKU) {String} category 品类
         * @apiSuccess (TraderSKU) {String} barcode 商品条形码
         * @apiSuccess (TraderSKU) {String} item_code 商品编码
         * @apiSuccess (TraderSKU) {String} name 商品名称
         * @apiSuccess (TraderSKU) {Number} price 经销价
         * @apiSuccess (TraderSKU) {Number} memo 备注
         */
        searchSKUs: function(session, { start, limit, brand, category, keyword, price_low, price_high, on_sale }) {

            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }

            var condition = ["is_removed == ?"];
            var params = [false];

            condition.push("ouid == ?");
            params.push(session.currentOU.id);

            if (brand) {
                condition.push("brand == ?");
                params.push(brand);
            }

            if (category) {
                condition.push("category == ?");
                params.push(category);
            }

            if (keyword) {
                condition.push("(name like ? or barcode like ? or item_code like ?)");
                params.push("%" + keyword + "%", "%" + keyword + "%", "%" + keyword + "%");
            }

            if (price_low) {
                condition.push("trader_price >= ?");
                params.push(Math.round(price_low * 100));
            }

            if (price_high) {
                condition.push("trader_price <= ?");
                params.push(Math.round(price_high * 100));
            }


            if (on_sale) {
                condition.push("on_sale == ?");
                params.push(true);
            }


            return lab.query("slime_trader_skus", {
                "conditions": condition,
                "params": params,
                "start": start,
                "limit": limit
            })
        },
        /**
         * @api {jsonrpc} slime@trader.batchDeleteSKUs()=result slime@trader.batchDeleteSKUs
         * @apiDescription 批量删除商品数据
         * @apiGroup slime
         * @apiSuccess {Object} changes 删除商品数据总数
         */
        // 批量删除
        batchDeleteSKUs: function(session) {

            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }

            return lab.snapshot(function(snapshot) {
                return snapshot.sqlite.query("update slime_trader_skus set is_removed == ? where ouid == ?", true, session.currentOU.id);
            })
        },
        // , SKU信息更新的时候的时候，下属trader的on_sale信息不用更新，
        //  调用其他模块方法这么操作：snapshot.slime.trader.xxxxx
        @updateSKU: function(ouid, { id, barcode, item_code, retail_unit, package, package_sku, brand, category, trader_price, image_url,on_sale }) {
            //如果没有找到sku的话，这么操作： throw @lab.errors.object_not_found;
            return lab.snapshot(function(snapshot) {
                return @.async(function() {

                    if (!id) {
                        throw @lab.errors.invalid_parameters;
                    }

                    snapshot.find("slime_trader_skus", id).then(function(sku) {

                        // WynnREADME : 尽量不要用Object.assign , 是坑， 直接用update， 交给@.merge.simple是比较好的一种实践

                        if (sku) {

                            if (sku.ouid == ouid) {

                                if (sku.source_ouid == ouid) {

                                    if (sku.barcode != barcode || sku.item_code != item_code) {
                                        throw @lab.errors.invalid_parameters;
                                    } else {
                                        snapshot.update("slime_trader_skus", sku, { barcode, item_code, retail_unit, package, package_sku, brand, category, trader_price, image_url,on_sale , last_update: Date.now() }).pipe(this);
                                    }

                                } else {
                                    snapshot.update("slime_trader_skus", sku, { on_sale , last_update: Date.now() }).pipe(this);
                                }

                            } else {
                                throw @lab.errors.no_permission;
                            }

                        } else {
                            throw @lab.errors.object_not_found;
                        }

                    }).pipe(this);

                }).then(function(existing_sku) {
                    // 接下来老套路，
                    // WynnREADME : 这里可能要处理一下
                    if (existing_sku.source_ouid == ouid) {

                        snapshot.sqlite.find("slime_trader_skus", {
                            "!": "id != source_id",
                            "source_id": existing_sku.source_id,
                            "ouid": ["!=", ouid]
                        }).then(function(result) {

                            @.async.all(result.records, function(sku) {

                                // WynnREADME : 这里on_sale， 是由下级经销商自行控制的, 其他自行控制字段的更新，以后也会塞在这里
                                snapshot.update("slime_trader_skus", sku, @.merge.simple(existing_sku, {
                                    id          : sku.id,
                                    ouid        : sku.ouid,
                                    last_update : Date.now(),
                                    on_sale     : sku.on_sale
                                })).pipe(this);

                            }).pipe(this);

                        }).pipe(this);

                    } else {
                        this.next(existing_sku);
                    }

                })
            })
        },

        // 创建SKU， item_code自动编码
        createSKU : function(session, {barcode, item_code, name, retail_unit, package, package_sku, brand, category, trader_price, image_url, on_sale}){

            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }

            return lab.snapshot(function(snapshot) {
                return snapshot.slime.brand.@findSKU(session.currentOU.id, {barcode, item_code, retail_unit, package, package_sku}).then(function(result) {
                    if (result.records.length) {
                        throw @lab.errors.object_existing;
                    } else {
                        if (!barcode && !item_code) {

                            snapshot.slime.core.@generateNextCode(session.currentOU.id, {type : 'trader_skus'}).then(function(code) {

                                snapshot.slime.brand.@importSKU(session.currentOU.id, {item_code : code, name, retail_unit, package, package_sku, brand, category, trader_price, image_url, on_sale}).pipe(this);

                            }).pipe(this);

                        } else {
                            snapshot.slime.brand.@importSKU(session.currentOU.id, {barcode, item_code, name, retail_unit, package, package_sku, brand, category, trader_price, image_url, on_sale}).pipe(this);
                        }
                    }
                });
            })
        }
    }
}